package cn.fl.institution.controller;

import cmm.comm.facade.framework.api.ISysCdMapApiService;
import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.condition.SysCdMapDQueryCondition;
import cmm.comm.facade.framework.dto.SysCdMapDDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DecimalUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.customer.service.ICstBscInfoService;
import cn.fl.customer.service.ICstNpBscInfoService;
import cn.fl.customer.vo.CstNpBscInfoVO;
import cn.fl.enums.TPCodeEnum;
import cn.fl.framework.base.constant.WebBaseConstant;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.project.api.IPrjCstAccInfoApiService;
import cn.fl.project.condition.PrjCstAccInfoQueryCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjBscExtService;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.service.IPrjCstAccInfoService;
import cn.fl.project.service.IProjectApiService;
import cn.fl.project.transform.PrjBscInfoVOTransform;
import cn.fl.project.vo.PrjBscInfoVO;
import cn.fl.project.vo.PrjCstAccInfoVO;
import cn.fl.system.service.ISysRegionService;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Description: 项目基础信息表 控制层  微众银行
 */
@Controller
@RequestMapping("/institution/webank")
public class PrjBscInfoInsWebankController {

	private static final Logger logger = LoggerFactory.getLogger(PrjBscInfoInsWebankController.class);

    @Autowired
    private IPrjBscInfoService prjBscInfoService; // 项目基础信息表

	@Autowired
	private IPrjCstAccInfoApiService prjCstAccInfoApiService; // 项目客户账户信息表
	
	@Autowired
	private ICstBscInfoService cstBscInfoService; // 客户基础信息
	
	@Autowired
	private ICstNpBscInfoService cstNpBscInfoService; // 自然人信息
	
	@Autowired
	private IPrjBscExtService prjBscExtService; //项目基础信息扩展表
	@Autowired
	private ISysRegionService sysRegionService;//查询省市县
	@Autowired
	private IPrjCstAccInfoService prjCstAccInfoService;//项目客户基础信息表
    @Autowired
    private ISysDictionaryApiService sysDictionaryApiService;
    @Autowired
    private IProjectApiService projectApiService;
    /**
     * 代码映射服务
     */
    @Autowired
    private ISysCdMapApiService sysCdMapApiService;

    /**
     * 微众银行新增或修改项目客户账户信息及校验
     */
    @RequestMapping(value = "/webankAddOrModifyPrjAccInfo.do", method = {RequestMethod.POST})
    @ResponseBody
    public DataResultVO webankAddOrModifyPrjAccInfo(HttpServletRequest request, HttpServletResponse response) {
        Long startTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "修改项目客户账户信息及校验"+ JSON.toJSONString(request.getParameterMap()), CurrentThreadContext.getCurrentUserName());
        String cstAccInfoId = request.getParameter("cstAccInfoId");//项目客户信息表id
        String insCode = request.getParameter("insCode");//机构code
        String prjId = request.getParameter("prjId");//项目id
        String cstId = request.getParameter("cstId");//客户id
        String cstNm = request.getParameter("cstNm");//客户姓名
        String bkNm = request.getParameter("bkNm");//银行名称
        String bkCd = request.getParameter("bkCd");//银行代码 -- 通用狮桥的数据字典表（CST0014） -- 资管特有的sys_cd_map_d表（M1041）
        String accNo = request.getParameter("accNo");//银行账号
        String mp = request.getParameter("mp");//手机号
        String bkNo = TPCodeEnum.getBkNo(bkNm);//开户行号
        String certNo = request.getParameter("certNo");//身份证
        String rgnPrCd = request.getParameter("rgnPrCd");//省
        String rgnCyCd = request.getParameter("rgnCyCd");//市
        String taxResDecCd = request.getParameter("taxResDecCd");//纳税居民申明
        String monthInc = request.getParameter("monthInc");//月收入
        DataResultVO dataResultVO = null;
        try {
            if (StringUtils.isEmpty(prjId)) {
                BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "项目id为空.", CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "项目信息不完整!");
            }
            if (StringUtils.isEmpty(cstId)) {
                BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "客户id为空", CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "客户信息不完整!");
            }
            if (StringUtils.isBlank(cstNm)) {
                BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "客户名称为空", CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "客户信息不完整!");
            }
            if(StringUtils.isBlank(bkNm) || StringUtils.isBlank(bkCd)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护开户银行信息!");
            }
            if(StringUtils.isBlank(accNo)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护银行卡号!");
            }
            if(StringUtils.isBlank(mp)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护银行预留手机号!");
            }
            /*if(StringUtils.isBlank(bkNo)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护开户行号!");
            }*/
            if(StringUtils.isBlank(monthInc)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护月收入!");
            }
            if(StringUtils.isBlank(rgnPrCd)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护区域-省!");
            }
            if(StringUtils.isBlank(rgnCyCd)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维区域-市!");
            }
            if(StringUtils.isBlank(taxResDecCd)){
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "请维护纳税居民申明!");
            }
            // 修改项目区域
            PrjBscInfoVO bscVo = new PrjBscInfoVO();
            bscVo.setId(Long.valueOf(prjId));
            bscVo.setRgnPrCd(rgnPrCd);
            bscVo.setRgnCyCd(rgnCyCd);
            BaseLogUtils.info(logger, "weBankAddOrModifyPrjAccInfo", "修改区域 bscvo"+ JSON.toJSONString(bscVo), CurrentThreadContext.getCurrentUserName());
            this.projectApiService.modifyPrjBscInfo2(PrjBscInfoVOTransform.toDTO(bscVo));
            // 修改自然人月收入
            CstNpBscInfoVO cstNpBscInfoVO = this.cstNpBscInfoService.selectById(Long.valueOf(cstId));
            if (StringUtils.isEmpty(taxResDecCd)) {
                taxResDecCd = "1";
            }
            if(null != cstNpBscInfoVO) {
                Long mrIncMoney = DecimalUtils.convertYuanToFen(Double.valueOf(monthInc)); // 月收入转为分
                Double yrInc = DecimalUtils.mul(mrIncMoney.doubleValue(),12d); // 月收入转换年收入
                if (!Objects.equals(cstNpBscInfoVO.getYrInc().doubleValue(), yrInc) || !Objects.equals(cstNpBscInfoVO.getRatepayingState(), taxResDecCd)) {
                    cstNpBscInfoVO.setYrInc(yrInc.longValue());
                    cstNpBscInfoVO.setRatepayingState(taxResDecCd);
                    BaseLogUtils.info(logger, "weBankAddOrModifyPrjAccInfo", "修改自然人信息 cstNpBscInfoVO"+ JSON.toJSONString(cstNpBscInfoVO), CurrentThreadContext.getCurrentUserName());
                    this.cstNpBscInfoService.modify(cstNpBscInfoVO);
                }
            }
            PrjCstAccInfoQueryCondition prjCstAccInfoQC = new PrjCstAccInfoQueryCondition();
            prjCstAccInfoQC.setPrjId(Long.valueOf(prjId));
            prjCstAccInfoQC.setIsDel(BaseConstant.IS_YESNO_NO);
            prjCstAccInfoQC.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_WEBANK);
            BaseLogUtils.info(logger, "weBankAddOrModifyPrjAccInfo", "根据prjId获取账户信息prjId"+prjId);
            List<PrjCstAccInfoVO> prjCstAccInfoVOS = this.prjCstAccInfoService.searchList(prjCstAccInfoQC);
            BaseLogUtils.info(logger, "weBankAddOrModifyPrjAccInfo", "根据prjId获取账户信息prjCstAccInfoVOS" + JSON.toJSONString(prjCstAccInfoVOS));
            PrjCstAccInfoQueryCondition condition = new PrjCstAccInfoQueryCondition();
            PrjCstAccInfoVO prjCstAccInfoVO = null;
            if (CollectionUtils.isNotEmpty(prjCstAccInfoVOS)) {
                prjCstAccInfoVO = prjCstAccInfoVOS.get(0);
                //说明该项目已存在账户信息 则跟据id进行修改
                condition.setId(prjCstAccInfoVO.getId());
            }

            bkNo = bkNo.trim();
            accNo = accNo.trim();
            certNo = certNo.trim();
            //查询映射表 校验银行卡bin 微众银行 以及所选银行
            SysCdMapDQueryCondition cdMapDQC = new SysCdMapDQueryCondition();
            cdMapDQC.setSysCd(WebBaseConstant.SYS_SYS_CD);
            cdMapDQC.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
            cdMapDQC.setmTypCd(PrjBscInfoConstant.WEBANK_BIN_CD);
            cdMapDQC.setsGrpCd(insCode);
            cdMapDQC.setsCode(bkCd);
            int length = accNo.length();
            BaseLogUtils.info(logger, "weBankAddOrModifyPrjAccInfo", "根据cdMapDQC查询映射:"+JSON.toJSONString(cdMapDQC));
            List<SysCdMapDDTO> sysCdMapDList =  this.sysCdMapApiService.searchSysCdMapDWithTargetList(cdMapDQC);
            String chkBinCd  = "0";
            String chkBinCdDesc  = "银行卡BIN校验不成功，建议换卡后再次尝试!";
            for(SysCdMapDDTO sysCdMapDDTO : sysCdMapDList) {
                if (Objects.equals(length, Integer.valueOf(sysCdMapDDTO.getCodeAttr2()))) {
                    for (int i = 3; i < 9; i++) {
                        String substring = accNo.substring(0, i);
                        if (Objects.equals(substring, sysCdMapDDTO.getTCode())) {
                            chkBinCd  = "1";
                            chkBinCdDesc  = "银行卡BIN校验成功.";
                        }
                    }
                }
            }
            if ("0" == chkBinCd) {
                return new DataResultVO(BaseConstant.IS_YESNO_NO, chkBinCdDesc);
            }

            condition.setPrjId(Long.valueOf(prjId));
            condition.setCstId(Long.valueOf(cstId));
            condition.setInsCode(insCode);
            condition.setCstNm(cstNm);
            condition.setAccNm(cstNm);
            condition.setBkCd(bkCd);
            condition.setBkNm(bkNm);
            condition.setBkNo(bkNo);
            condition.setAccNo(accNo);
            condition.setMp(mp);
            condition.setCertNo(certNo);
            condition.setCertTypCd(DictionaryConstant.CODE_CERT_TYP_CD_0);
            condition.setChkBinCd(chkBinCd);
            dataResultVO = this.prjCstAccInfoService.modifyPrjAccInfo(condition);
            if(BaseConstant.IS_YESNO_YES == dataResultVO.getSuccess()){
                Map<String,String> resultMap = (Map<String, String>) dataResultVO.getData();
                String chkRstCd;
                String rstDesc;
                chkRstCd = resultMap.get("chkRstCd");
                rstDesc = resultMap.get("rstDesc");
                if (chkRstCd.equals("1")) {
                    dataResultVO.setSuccess(BaseConstant.IS_YESNO_YES);
                    dataResultVO.setInfo("四要素信息校验通过");
                } else {
                    dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
                    dataResultVO.setInfo(rstDesc);
                }
            }
        } catch (BaseException ex) {
            dataResultVO.setSuccess(BaseConstant.IS_YESNO_NO);
            dataResultVO.setInfo(ex.getMessage());
            BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "新增或修改项目客户账户信息及校验,prjId:" + prjId + ".ERROR:" + ex.getMessage(), CurrentThreadContext.getCurrentUserName());
        }catch (Exception e){
            BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "保存失败，系统异常",CurrentThreadContext.getCurrentUserName()+e.getMessage(),e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "保存失败，系统异常");
        }
        BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "新增或修改项目客户账户信息及校验返回=" + JSON.toJSONString(dataResultVO), CurrentThreadContext.getCurrentUserName());
        Long endTm = System.currentTimeMillis();
        BaseLogUtils.info(logger, "webankAddOrModifyPrjAccInfo", "新增或修改项目客户账户信息及校验, PRJID:" + prjId, "-耗时:" + (endTm - startTm));
        return dataResultVO;
    }

}
